<?php
/**
 * [ Random Framework ]
 *
 * @version 2.0.0 (build 20130520)
 *
 * @link http://0x00.sinaapp.com/random.html
 * 
 * @author Coseylee (Coseylee@gmail.com).
 *
 */

/**
 * MySQLi 数据库操作类
 */
class mysqli_db extends random_database
{
	private $connect; // 当前连接
	private $results; // 上一次结果集
	private static $count = 0; // 查询次数
	private static $sqls = array(); // 查询语句与时间
	
	/**
	 * 连接数据库
	 * 
	 * @param array $db_config 参数
	 */
	function __construct($db_config)
	{
		if (function_exists('mysqli_connect') === false)
		{
			throw new random_exception('Dont Support MySQLi');
			exit;
		}
		if (!$this -> connect = @mysqli_connect($db_config['host'], $db_config['user'], $db_config['pass'], $db_config['name'], $db_config['port']))
		{
			throw new random_exception('Can\'t Connect MySQL Server Or Select MySQL Database');
			exit;
		}
		if ($this -> getVersion() > '4.1')
		{
			$this -> query('SET NAMES utf8', $this -> connect);
		}
	}
	
	/**
	 * 获取 MySQL 版本
	 * 
	 */
	function getVersion()
	{
		return mysqli_get_client_version();
	}
	
	/**
	 * 插入操作
	 * 
	 * @param $table 表名
	 * @param $data 数组形式的插入数据
	 * @param $replace 是否替换插入
	 */
	function insert($table, $data, $replace = false)
	{
		if(!is_array($data) || empty($table) || count($data) == 0)
		{
			return '';
		}
		$field = array_keys($data);
		$value = array_values($data);
		$field = array_map(array($this, 'add_char'), $field);
		$value = array_map(array($this, 'add_quote'), $value);
		$field = implode(',', $field);
		$value = implode(',', $value);
		$sql = $replace == true ? 'REPLACE INTO ' : 'INSERT INTO ';
		$sql .= "`{$table}`({$field}) VALUES({$value})";
		return $sql;
	}
	
	/**
	 * 查询
	 * 
	 * @param $table 表名
	 * @param $where 查询条件（数组或字符串）
	 * @param $order 排序条件（字符串）
	 * @param $limit 限制（字符串）
	 * @param $data 查询字段（字符串）
	 */
	function select($table, $where = '', $order = '', $limit = '', $data = '*')
	{
		if ($data == '') return '';
		
		if (empty($where))
		{
			$where =  '';
		}
		elseif (is_array($where))
		{
			$temp = array();
			foreach ($where as $field => $value)
			{
				$temp[] = $this -> add_char($field).' = '.$this -> add_quote($value);
			}
			$where = ' WHERE '.implode(' AND ', $temp);
		}
		else
		{
			$where = ' WHERE '.$where;
		}
		
		$order = empty($order) ? '' : ' ORDER BY '.$order;
		$limit = empty($limit) ? '' : ' LIMIT '.$limit;
		
		if ($data != '*')
		{
			$fields = explode(',', $data);
			$fields = array_map(array($this, 'add_char'), $fields);
			$data = implode(',', $fields);
		}
		
		unset($temp, $fields);
		
		$sql = "SELECT {$data} FROM `{$table}`".$where.$order.$limit;
		return $sql;
	}
	
	/**
	 * 查询一条记录
	 * 
	 * @param $table 表名
	 * @param $where 查询条件（数组或字符串）
	 * @param $order 排序条件（字符串）
	 * @param $data 查询字段（字符串）
	 */
	function select_one($table, $where = '', $order = '', $data = '*')
	{
		return $this -> select($table, $where, $order, 1, $data);
	}
	
	/**
	 * 更新操作
	 * 
	 * @param $table 表名
	 * @param $data 数组形式的数据
	 * @param $where 条件（数组或字符串）
	 */
	function update($table, $data, $where)
	{
		if (is_string($data) && !empty($data))
		{
			$fields = $data;
		}
		elseif (is_array($data) && !empty($data))
		{
			$fields = array();
			foreach ($data as $field => $value)
			{
				switch (substr($value, 0, 2))
				{
					case '+=':
					{
						$value = substr($value, 2);
						if (is_numeric($value))
						{
							$fields[] = $this -> add_char($field).' = '.$this -> add_char($field).' + '.$this -> add_quote($value);
						}
						else
						{
							continue;
						}
					}
					break;
					case '-=':
					{
						$value = substr($value, 2);
						if (is_numeric($value))
						{
							$fields[] = $this -> add_char($field).' = '.$this -> add_char($field).' - '.$this -> add_quote($value);
						}
						else
						{
							continue;
						}
					}
					break;
					default:
					$fields[] = $this -> add_char($field).' = '.$this -> add_quote($value);
				}
			}
			$fields = implode(',', $fields);
		}
		else
		{
			return '';
		}
		
		if (is_array($where) && !empty($where))
		{
			$w = array();
			foreach ($where as $field => $value)
			{
				$w[] = $this -> add_char($field).' = '.$this -> add_quote($value);
			}
			$where = implode(' AND ', $w);
		}
		$sql = "UPDATE `{$table}` SET ".$fields.' WHERE '.$where;
		return $sql;
	}
	
	/**
	 * 删除操作
	 * 
	 * @param $table 表名
	 * @param $where 条件（数组或字符串）
	 */
	function delete($table, $where)
	{
		if (empty($where)) return '';
		if (is_array($where))
		{
			$w = array();
			foreach ($where as $field => $value)
			{
				$w[] = $this -> add_char($field).' = '.$this -> add_quote($value);
			}
			$where = implode(' AND ', $w);
		}
		$sql = "DELETE FROM `{$table}` WHERE ".$where;
		return $sql;
	}
	
	/**
	 * 执行语句
	 * 
	 * @param $sql SQL语句
	 */
	function query($sql)
	{
		$debug[0] = $sql;
		$debug[1] = microtime(true);
		$this -> results = mysqli_query($this -> connect, $sql);
		$debug[1] = sprintf('%.6f', microtime(true) - $debug[1]);
		if ($this -> results === false)
		{
			$message = $sql.'<br />';
			$message .= '-'.mysqli_errno($this -> connect).'<br />';
			$message .= '-'.mysqli_error($this -> connect).'<br />';
			throw new random_exception($message, false);
			exit;
		}
		++self::$count && self::$sqls[] = $debug;
		unset($sql, $debug);
		return $this -> results;
	}
	
	/**
	 * 返回一行带关联数组的结果集
	 * 
	 * @param $results 结果集
	 */
	function fetch_array($results)
	{
		return mysqli_fetch_array($results, MYSQLI_ASSOC);
	}
	
	/**
	 * 返回一行索引的结果集
	 * 
	 * @param $results 结果集
	 */
	public function fetch_row($results)
	{
		return mysqli_fetch_array($results, MYSQLI_NUM);
	}
	
	/**
	 * 快速获取下一条记录
	 * 
	 */
	function fetch_next()
	{
		$return = $this -> fetch_array($this -> results);
		return $return;
	}
	
	/**
	 * 开始事务
	 * 
	 */
	function start()
	{
		return mysqli_autocommit($this -> connect, false);
	}
	
	/**
	 * 事务提交
	 * 
	 */
	function commit()
	{
		return mysqli_commit($this -> connect);
	}
	
	/**
	 * 事务回滚
	 * 
	 */
	function rollback()
	{
		return mysqli_rollback($this -> connect);
	}
	
	/**
	 * 释放结果集
	 * 
	 */
	function free_result()
	{
		if(is_resource($this -> results))
		{
			mysqli_free_result($this -> results);
			$this -> results = null;
		}
		return true;
	}
	
	/**
	 * 返回结果集行数
	 * 
	 * @param $results 结果集
	 */
	function num_rows($results)
	{
		return mysqli_num_rows($results == null ? $this -> results : $results);
	}
	
	/**
	 * 返回影响行数
	 * 
	 */
	function affected_rows()
	{
		return mysqli_affected_rows($this -> connect);
	}
	
	/**
	 * 最后插入的ID
	 * 
	 */
	function insert_id()
	{
		return mysqli_insert_id($this -> connect);
	}
	
	/**
	 * 返回查询次数
	 * 
	 */
	function query_count()
	{
		return self::$count;
	}
	
	/**
	 * 返回所有查询语句
	 * 
	 */
	function sqls()
	{
		return self::$sqls;
	}
	
	/**
	 * 添加反引号
	 * 
	 */
	function add_char($field)
	{
		if ($field == '*' || strpos($field, '(') !== false || strpos($field, '.') !== false || strpos($field, '`') !== false)
		{
			return trim($field);
		}
		else
		{
			return '`'.trim($field).'`';
		}
	}
	
	/**
	 * 添加单引号
	 * 
	 */
	function add_quote($value)
	{
		return '\''.mysqli_real_escape_string($this -> connect, $value).'\'';
	}
	
	/**
	 * 关闭连接
	 * 
	 */
	function close()
	{
		if($this -> connect == true) @mysqli_close($this -> connect);
	}
}